#ifndef MAP_H
#define MAP_H



#include "includes.h"
#include "init.h"
#include "units.h"



class object;
class bonus;



/** @brief Main map class - contains terrain and objects
*
*   \image html map.jpeg
*/
class mapa
{

public:

	/**	@brief	Function for obaining the singleton
	*	@return	pointer to the singleton
	*/
	static mapa* get_instance();

	//! @brief Deletes terrain map and from objects only bonuses
	void rebuild();
	
	/** @brief Sets object do the map
	*	@param o object to set
	*	@param	x x coordinate, here to palce the object, constraint: 0 <= x < state->map->size_x
	*	@param	y y coordinate, here to palce the object, constraint: 0 <= y < state->map->size_y
	*/
	void set_object( object* o, unsigned int x, unsigned int y );
	/** @brief	Gets object from map
	*	@param	x x coordinate, from where to get the object, constraint: 0 <= x < state->map->size_x
	*	@param	y y coordinate, from where to get the object, constraint: 0 <= y < state->map->size_y
	*	@return	pointer to the object
	*/
	object* get_object( unsigned int x, unsigned int y );

	/** @brief	Loads map terrain from stream
	*	@param	is data stream with map
	*	first two numbers contains size_x size_y, other numbers terrain information
	*	10 - 100: terrain
	*	20000: water
	*	30000: wall
	*	number % 10: beginning place of player with this number
	*	@return	true, if loading is successful, else false
	*/
	bool load( istream& is );
	/** @brief	Loads map objects from stream
	*	@param	is data stream with objects
	*	file structure: "Type	Name	Pos_x	Pos_y	Health	Player_id"
	*	#: comment
	*	@return	true, if loading is successful, else false
	*/
	bool load_objects( istream& is );
	/** @brief	Loads map terrain from file
	*	@param	file file, where the map is stored
	*	first line contains size_x size_y, other lines terrain information
	*	10 - 100: terrain
	*	20000: water
	*	30000: wall
	*	number % 10: beginning place of player with this number
	*	@return	true, if loading is successful, else false
	*/
	bool load( const char* file );
	/** @brief	Loads map objects from file
	*	@param	file file, where the objects are stored
	*	file structure: "Type	Name	Pos_x	Pos_y	Health	Player_id"
	*	#: comment
	*	@return	true, if loading is successful, else false
	*/
	bool load_objects( const char* file );

	/** @brief Saves current objects to file
	*	@param file filename, where to save the objects
	*/
	void save_objects( const char* file );

	/** @brief	Creates clone of the terrain
	*	@return	pointer to the cloned array
	*/
	array2d< unsigned int >* terrain_clone();

	/**	@brief Saves 2D array of numbers to file
	*	@param map 2D array of numbers to save, constraint: map != 0
	*	@param file filename where to save the numbers
	*	@param sx x size of the array, constraint: sx <= map->s_x
	*	@param sy y size of the array, constraint: sy <= map->s_y
	*/
	static void export_map( array2d< unsigned int >* map, const char* file, unsigned int sx, unsigned int sy );

	/** @brief	Gets x size of the map
	*	@return	x size
	*/
	unsigned int get_size_x()
	{
		return size_x;
	};
	/** @brief	Gets y size of the map
	*	@return	y size
	*/
	unsigned int get_size_y()
	{
		return size_y;
	};

	//! @brief Cleans all objects from objects map
	void clean_map();
	
	//! 2D array of objects
	array2d< object* >* objects;
	//! 2D array of numbers representating map terrain
	array2d< unsigned int >* terrain;

	int x;


private:

	mapa( int _x );
	mapa( const mapa& );
	mapa& operator=( const mapa& x );
	//! @brief Deletes terrain map and from objects only bonuses
	~mapa();


	/** @brief	Parses lines when loading objects from file
	*	@param	ol line to parse
	*	@return	true if parsing successful, else false
	*/
	bool parse_objects_line( const string& ol );

	//! x size
	unsigned int size_x;
	//! y size
	unsigned int size_y;

};



#endif